// GoalieTactics.h

// Definovanie funkcii bezprostredne suvisiacich s taktickou strankou brankara


#ifndef GOALIETACTICS_H
#define GOALIETACTICS_H

#include "Player/PlayerSkills.h"
//#include "Common/Main.h"
//#include "Common/Support/Debug.h"

const int CYCLES_TO_RUN_HOME_AFTER_KICK = 10;
// Aka je minmalna pozadovane (ocakavana) rychlost lopty na brankovej ciare, ktora sa detekuje ako strela na branu?
const float SPEED_ON_GOAL_LINE_MIN = 0.05f;

enum CSKickOff {
	CSKO_GOFORBALL,		//brankar musi ist za loptou
	CSKO_CAUGHT,		//lopta je zachytena
	CSKO_SCAN,			//sledovanie situacie
	CSKO_KICK,			//rozohratie, pozicia je uz najdena
	CSKO_GOHOME			//po rozohrati sa vraciam naspat do svojej pozicie
};

// Modul taktickej stranky brankara
class GoalieTactics : public PlayerSkills
{
	bool caughtBall;
	bool enemyHadBall;
	bool bWeLastTouchedBall;
	bool inPosition;
	bool scaningSituation;
	int goalieKicked;
	Point homePos;

protected:
	// csefkove nove fcie
	float cs_me_ballDistance;
	bool cs_natocenie_dolava;
	Point cs_stred_brany;
	CSKickOff cs_kickoff;

	virtual void LPT_Main();
	void LPT_BallUnknown();
	bool LPT_TurnBody(bool left,float odch);
	void LPT_DefenseLine();
	void LPT_DefensePoint(Point &p,bool &Left);
	bool LPT_PohybNalavo(Point newPosition);
	void LPT_KickOff();
	void LPT_BallHeadingOnGoal();
	bool LPT_PassNearGoal();
	bool LPT_CatchBall();
	bool LPT_Kick();
	float LPT_GetBestDash(const Point& pointFuture,const Myself& me,Point &bestPoint,float step);
	bool LPT_Intercept2Cycles(float catch_coef);
	void LPT_Dash(float DashPower);
	void LPT_Turn(float TurnMoment);
	void LPT_LookAtBall();
	bool LPT_DangerousBall();
	float LPT_MaxTurnInDegree();
	// Funkcie definujuce spravanie sa brankara
	virtual void BehaveWithBallGoalie();
	virtual void BehaveWithoutBallGoalie();
	virtual void BehaveWithoutBallKnowledgeGoalie();

	// Vypocita vzdialenost k branke
	float DistanceToGoal(const Point&, bool bOur = false) const;
	// Vrati vhodnu defenzivnu poziciu pre brankara
	Point GetDefensePos();
	// Vrati domovsku poziciu brankara
	virtual Point GetHomePos();
	// Vrati bod, z ktoreho je najvhodnejsie vykopavat
	Point GetKickOffPos() const;
	// Nachadza sa bod v pokutovom uzemi?
	bool InPenaltyArea(const Point p);
	// Su naokoli superi, ak nie dribluj
	bool NoEnemiesAround(float dist=5.0f) const;
	bool NoEnemiesAround(const Point p,float dist=5.0f) const;
	int NumberOfEnemiesAround(const Point p,float dist=5.0f) const;
	// Hlada najvhodnejsie natocenie hraca, tento parameter sa potom pouzije vo funkcii DribbleTo2
	bool SmartDribleTo(const Point&);

public:
	// Konstruktor
	GoalieTactics(bool new_goalie = true);
	// Destruktor
	virtual ~GoalieTactics(){}

	// Smeruje lopta na nasu branku?
	bool BallHeadingOnOurGoal(float tolerance = 10.f);

	// Je hrac zodpovedny za loptu?
	bool DependentForBall() const;
		
	// Vrati supera najblizsieho k danemu bodu (podla hracovej VI) a pocet cyklov potrebnych pre dobehnutie do daneho bodu
	// maximalnou rychlostou
	int GetNearestEnemyTo(const Point& pos, int* pCycles) const;

	// Vrati spoluhraca najblizsieho k danemu bodu (podla hracovej VI) a pocet cyklov potrebnych pre dobehnutie do daneho bodu
	// maximalnou rychlostou
	int GetNearestFriendTo(const Point& pos, int* pCycles) const;

	// Vrati najvhodnejsieho hraca na prihranie. Vrati sa -1, ak sa nenajde ziadny hrac
	int GetPassAbleFriend() const;

	// Superov hrac najblizsie k lopte
	int NearEnemy(int* pCycles) const;
	
	// Nas hrac najblizsie k lopte. Vrati -1, ak je to tento 
	int NearFriend(int* pCycles) const;

	// Prihrava super loptu svojmu spoluhracovi blizko nasej branky?
	bool IsPassNearGoal();
	
	// Je zadany bod medzi zvysnymi dvoma bodmi?
	bool InTheMiddle(const Point& tested, const Point& p1,const Point& p2) const;

	
	
	// NASLEDUJU FUNKCIE, KTORE JE VHODNE PREROBIT
	//--------------------------------------------
	
	// Vrati najblizsi bod, kde brankar dokaze zachytit loptu
	Point GetNearestBallInterceptPos();
	
	// Vrati bod, na ktorom brankar bude moct vhodne zasiahnut proti prihravke pred brankou
	Point SolvePassNearGoal();

	// -------------------------------------------

};

#endif	// GOALIETACTICS_H
